Skip to content

feat(app-server): add history_mode to thread - #29927

Merged
owenlin0 merged 10 commits into
mainfrom
owen/add_thread_history_mode
Jun 26, 2026
Merged

feat(app-server): add history_mode to thread#29927
owenlin0 merged 10 commits into
mainfrom
owen/add_thread_history_mode

Conversation

@owenlin0

@owenlin0 owenlin0 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a new historyMode = "legacy" | "paginated" to Thread. This will be stored in SessionMeta in the JSONL rollout file and as a new column in the SQLite thread_metadata table, and exposed on thread/start and on the Thread object in app-server.

What changed

  • Added canonical ThreadHistoryMode with legacy and paginated, defaulting old and new SessionMeta to legacy.
  • Carried history_mode through core session config, ThreadStore stored metadata, local/in-memory stores, rollout metadata extraction, and the existing SQLite threads table.
  • Added experimental historyMode to app-server v2 Thread and thread/start.
  • Made paginated stored threads metadata-discoverable but unsupported for legacy full-history reads, load_history, live resume, and create paths.
  • Regenerated app-server schema fixtures and added protocol/state/thread-store/app-server coverage for persistence and fail-closed behavior.

Compatibility floor

Because users may be running various versions of Codex binaries on the same machine (TUI, Codex App, etc.), we will need to establish a compatibility floor for upcoming paginated threads, which will change how thread storage reads and writes work.

The overall plan here:

Release N:
- Add historyMode to SessionMeta / Thread / SQLite metadata.
- Teach binaries to understand paginated threads.
- If a binary sees `historyMode="paginated"` but does not support the paginated contract, it refuses to resume/mutate the thread.
- Default remains `"legacy"`.

Release N+1:
- First-party clients start opting into paginated threads where appropriate.
- Internal dogfood / staged rollout.
- Measure old-client usage and paginated-thread unsupported errors.

Release N+2:
- Only after Release N+ is overwhelmingly deployed, make paginated the default.
- Accept that a small tail of N-1-or-older binaries may not understand paginated threads.

The important behavior change is fail-closed handling for a binary that encounters a persisted paginated thread before it knows how to fully support paginated history. In app-server, if a thread is paginated, we will:

  • allow metadata-only discovery paths like thread/list and thread/read(includeTurns=false), so clients can still see the thread and inspect its historyMode
  • reject legacy full-history/live-thread paths like thread/read(includeTurns=true) and thread/resume with an unsupported JSON-RPC error
  • avoid silently treating an unknown or future historyMode as legacy

Under the hood, the ThreadStore layer also rejects legacy operations that would need to load or replay the full thread history for a paginated thread. That gives us the behavior we want for Release N: future paginated threads are visible, but this binary fails closed instead of trying to operate on them as if they were legacy threads.

@owenlin0 owenlin0 changed the title add history_mode to thread feat(app-server): add history_mode to thread Jun 25, 2026
@owenlin0
owenlin0 force-pushed the owen/add_thread_history_mode branch from d058227 to 311883f Compare June 25, 2026 17:23
@owenlin0
owenlin0 marked this pull request as ready for review June 25, 2026 18:42
@owenlin0
owenlin0 requested a review from a team as a code owner June 25, 2026 18:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 311883fa89

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/thread-store/src/local/read_thread.rs
Comment thread codex-rs/app-server-protocol/src/protocol/v2/thread.rs
@owenlin0
owenlin0 force-pushed the owen/add_thread_history_mode branch from 311883f to c953f53 Compare June 25, 2026 18:52
@owenlin0
owenlin0 force-pushed the owen/add_thread_history_mode branch from 8ef00eb to f3655c0 Compare June 25, 2026 19:55
Comment thread codex-rs/state/src/runtime/threads.rs
Comment thread codex-rs/thread-store/src/in_memory.rs
///
/// The default is legacy so existing stores stay compatible. Stores whose durable contract is
/// already paginated should override this instead of relying on core to infer storage behavior.
fn default_history_mode(&self) -> ThreadHistoryMode {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be a top level read attr, or should it be a property of thread metadata?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think top-level is right for now. This is the store fallback for histories that do not already carry persisted thread metadata, mainly so a remote paginated store can opt into its durable contract. Persisted threads still carry the actual mode in SessionMeta / thread metadata.

Comment thread codex-rs/thread-store/src/types.rs Outdated

@wiltzius-openai wiltzius-openai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some detail q's but looks good

Comment thread codex-rs/thread-store/src/types.rs
Comment thread codex-rs/state/src/runtime/memories.rs
Comment thread codex-rs/thread-store/src/local/read_thread.rs
Comment thread codex-rs/rollout/src/list.rs
Comment thread codex-rs/rollout/src/recorder.rs Outdated
Comment thread codex-rs/protocol/src/protocol.rs
Comment thread codex-rs/rollout/src/recorder.rs Outdated
},
selected_capability_roots,
memory_mode: (!config.generate_memories()).then_some("disabled".to_string()),
history_mode: Default::default(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still hardcode SessionMeta.history_mode = legacy when creating the rollout
Since CreateThreadParams.history_mode never reaches RolloutRecorder, the JSONL compatibility floor isn’t actually established yet. enabling paginated later would still write legacy-looking rollouts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or am I missing something?

@owenlin0 owenlin0 Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah this PR doesn't actually support history_mode = "paginated" yet (we throw a json-rpc error), so codex decided to hardcode this instead of plumbing it through properly. I'll plumb it through properly now though so it's not confusing

@owenlin0
owenlin0 force-pushed the owen/add_thread_history_mode branch from 9523797 to 4d6ed79 Compare June 26, 2026 15:42
@owenlin0
owenlin0 force-pushed the owen/add_thread_history_mode branch from 4d6ed79 to c80f9bc Compare June 26, 2026 15:49
@owenlin0
owenlin0 merged commit 5267e80 into main Jun 26, 2026
31 checks passed
@owenlin0
owenlin0 deleted the owen/add_thread_history_mode branch June 26, 2026 16:12
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants